import datetime

from utils.database import execute_query, execute_update
from utils.logger import get_logger, INFO

# 创建每日总结专用的日志器
summary_logger = get_logger("daily_summary", level=INFO, daily_rotation=True)


class DailyDataSummarizer:
    """每日数据汇总类，用于生成当日数据总结"""

    def __init__(self):
        """初始化每日汇总器"""
        self.is_running = False
        self.job_id = 'daily_summary_job'

    def start(self, scheduler=None):
        """启动每日汇总任务

        Args:
            scheduler: 调度器实例，如果为None则不会自动注册任务
        """
        if not self.is_running and scheduler:
            # 添加每天00:00执行的定时任务
            scheduler.add_job(
                self.log_daily_summary,
                'cron',
                hour=0,
                minute=0,
                id=self.job_id
            )

            self.is_running = True
            summary_logger.info("每日数据总结任务已启动，执行时间: 每日00:00")

    def stop(self, scheduler=None):
        """停止每日汇总任务

        Args:
            scheduler: 调度器实例，如果为None则不会自动注销任务
        """
        if self.is_running and scheduler:
            scheduler.remove_job(self.job_id)
            self.is_running = False
            summary_logger.info("每日数据总结任务已停止")

    def log_daily_summary(self):
        """记录每日数据总结（具体逻辑由调用方实现）"""
        try:
            summary_logger.info("开始生成summary数据")
            ## 首先查询所有设备mac地址
            sql = "SELECT `user`.DataName, `user`.`sbp`, `user`.`dbp` FROM `user` RIGHT JOIN checkin ON `user`.Uid = checkin.uid"
            userData = execute_query(sql)
            summary = {
                'summary_date': (datetime.datetime.now() - datetime.timedelta(days=1)).strftime("%Y-%m-%d"),
                'hr_exception_cnt': 0,
                'pressure_exception_cnt': 0,
                'rr_exception_cnt': 0,
                'sleep_exception_cnt': 0,
                'hrv_watch_exception_cnt': 0,
                ## 总人数
                'all_cnt': 0,
                ## 异常总人数
                'exception_cnt': 0,
                ## 平均指数
                'average_score': 0,
                ## 心脑血管事件风险
                'cv_exception_cnt': 0,
                ## 创建时间
                'create_time': datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                ## 心率过速人数
                'hr_overspeed_cnt': 0,
                ## 心率过缓人数
                'hr_slowspeed_cnt': 0,
                ## 呼吸过速人数
                'rr_overspeed_cnt': 0,
                ## 呼吸过缓人数
                'rr_slowspeed_cnt': 0,
                ## 深浅睡眠异常人数
                'deep_light_sleep_exception_cnt': 0,
                ## 快速眼动异常人数
                'rem_exception_cnt': 0,
                ## 睡眠周期异常人数
                'sleep_cycle_exception_cnt': 0,
                ## 心率或血压异常的人数
                'hr_pressure_exception_cnt': 0,
                ## 呼吸暂停异常人数
                'rr_pause_cnt': 0
            }
            for user in userData:
                if user['DataName'] is None:
                    continue
                hr_test = True
                pressure_test = True
                rr_test = True
                sleep_test = True
                hrv_watch_test = True
                cv_test = True
                exception_test = True
                hr_overspeed_test = True
                hr_slowspeed_test = True
                rr_overspeed_test = True
                rr_slowspeed_test = True
                deep_light_sleep_test = True
                rem_test = True
                sleep_cycle_test = True
                rr_pause_test = True
                user_summary = {
                    'mac': user['DataName'],
                    ## 已经到零点了，所以日期应该是昨天
                    'summary_date': (datetime.datetime.now() - datetime.timedelta(days=1)).strftime("%Y-%m-%d"),
                    ## 呼吸暂停次数
                    'rr_pause_cnt': 0,
                    ## 创建时间
                    'create_time': datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                    ## 最后一次总结的btm
                    'last_summary_btm': None,
                    ## 当日平均健康指数评分
                    'score': 0,
                }
                ## 查询该用户最后一次总结summary数据的btm
                sql = "SELECT * FROM single_summary WHERE mac = '" + user[
                    'DataName'] + "' AND last_summary_btm IS NOT NULL ORDER BY create_time DESC LIMIT 1"
                last_summary = execute_query(sql)
                ## 开始查询要总结的-00数据
                if len(last_summary) == 0:
                    ## 总结所有数据
                    sql = "SELECT * FROM `" + user['DataName'] + "-00` ORDER BY BTM DESC LIMIT 1"
                else:
                    ## 只总结没总结的
                    sql = "SELECT * FROM `" + user['DataName'] + "-00` WHERE BTM > '" + last_summary[0][
                        'last_summary_btm'] + "'"
                data = execute_query(sql)
                for d in data:
                    ## 呼吸暂停次数
                    user_summary['rr_pause_cnt'] += d['Apnea']
                    ## 检查心率是否异常
                    if hr_test and (d['HRHigh'] > 0 or d['HRLow'] > 0):
                        summary['hr_exception_cnt'] += 1
                        hr_test = False
                    ## 检查心率是否过速
                    if hr_overspeed_test and d['HRHigh'] > 0:
                        summary['hr_overspeed_cnt'] += 1
                        hr_overspeed_test = False
                    ## 检查心率是否过缓
                    if hr_slowspeed_test and d['HRLow'] > 0:
                        summary['hr_slowspeed_cnt'] += 1
                        hr_slowspeed_test = False
                    ## 检查心跳是否暂停
                    if rr_pause_test and d['Apnea'] > 0:
                        summary['rr_pause_cnt'] += 1
                        rr_pause_test = False
                    # 检查呼吸是否过速
                    if rr_overspeed_test and d['RRHigh'] > 0:
                        summary['rr_overspeed_cnt'] += 1
                        rr_overspeed_test = False
                    # 检查呼吸是否过缓
                    if rr_slowspeed_test and d['RRLow'] > 0:
                        summary['rr_slowspeed_cnt'] += 1
                        rr_slowspeed_test = False
                    ## 检查血压是否异常
                    if pressure_test:
                        ## 这一条的PlotDB详细数据
                        sql = "SELECT SP, DP FROM `" + d['PlotDB'] + "`"
                        detail_data = execute_query(sql)
                        for detail in detail_data:
                            if detail['SP'] > user['sbp'] or detail['DP'] > user['dbp']:
                                summary['pressure_exception_cnt'] += 1
                                pressure_test = False
                                break
                    ## 检查呼吸是否异常
                    if rr_test:
                        if d['RRHigh'] > 0 or d['RRLow'] > 0:
                            summary['rr_exception_cnt'] += 1
                            rr_test = False
                    ## 检查睡眠是否异常
                    ## 判断深浅睡眠比例失常
                    if deep_light_sleep_test:
                        if (d['DSR'] > 20 or d['DSR'] < 15):
                            deep_light_sleep_test = False
                            summary['deep_light_sleep_exception_cnt'] += 1
                    ## 判断快速眼动异常
                    if rem_test:
                        if (d['REMR'] > 25 or d['REMR'] < 20):
                            rem_test = False
                            summary['rem_exception_cnt'] += 1
                    ## 判断睡眠周期异常
                    if sleep_cycle_test:
                        if (d['SleepCycle'] > 6 or d['SleepCycle'] < 4):
                            sleep_cycle_test = False
                            summary['sleep_cycle_exception_cnt'] += 1
                    if (d['DSR'] > 20 or d['DSR'] < 15) and sleep_test:
                        sleep_test = False
                        summary['sleep_exception_cnt'] += 1
                    if (d['LSR'] > 65 or d['LSR'] < 50) and sleep_test:
                        sleep_test = False
                        summary['sleep_exception_cnt'] += 1
                    ## 判断快速眼动异常
                    if (d['REMR'] > 25 or d['REMR'] < 20) and sleep_test:
                        sleep_test = False
                        summary['sleep_exception_cnt'] += 1
                    ## 判断睡眠周期异常
                    if (d['SleepCycle'] > 6 or d['SleepCycle'] < 4) and sleep_test:
                        sleep_test = False
                        summary['sleep_exception_cnt'] += 1
                    ## 检查心脑血管事件
                    if cv_test and (d['CardiovascularEventIndex'] > 50 or d['CardiovascularEventIndex'] <= 25):
                        summary['cv_exception_cnt'] += 1
                        cv_test = False
                    ## 判断HRV异常
                    ## 判断心脏总能量指数是否正常(todo:这里是用预警的还是危险的阈值)
                    if hrv_watch_test and (d['TotalCardiacEnergy'] > 6000 or d['TotalCardiacEnergy'] < 1000):
                        hrv_watch_test = False
                        summary['hrv_watch_exception_cnt'] += 1
                    ## 判断平均心率是否正常
                    if hrv_watch_test and (d['AHR'] > 120 or d['AHR'] < 60):
                        hrv_watch_test = False
                        summary['hrv_watch_exception_cnt'] += 1
                    ## 判断神经系统指数是否正常
                    if hrv_watch_test and (d['NervousSystemIndex'] > 100 or d['NervousSystemIndex'] < 50):
                        hrv_watch_test = False
                        summary['hrv_watch_exception_cnt'] += 1
                    ## 判断心率减速力是否正常
                    if hrv_watch_test and (d['HRDF'] < 4.5 or d['HRDF'] > 10000):
                        hrv_watch_test = False
                        summary['hrv_watch_exception_cnt'] += 1
                    ## 判断情绪压力是否正常
                    ## 先计算情绪压力指数
                    emotion_indicator = d['NervousSystemIndex']
                    # 假设 emotion_indicator 已经定义
                    if emotion_indicator >= 5:
                        emotion_indicator = 4.8
                    deal_indicator_ok = 0
                    if emotion_indicator >= 0.4 and emotion_indicator < 1.6 and deal_indicator_ok == 0:
                        deal_indicator_ok = 1
                        abs_val = abs(emotion_indicator - 1)
                        emotion_indicator = 100 - (abs_val / 0.6) * 30
                    if emotion_indicator >= 2.56 and emotion_indicator < 3.46 and deal_indicator_ok == 0:
                        deal_indicator_ok = 1
                        abs_val = abs(emotion_indicator - 3.01)
                        emotion_indicator = 100 - (abs_val / 0.45) * 30
                    if emotion_indicator >= 1.6 and emotion_indicator <= 2.56 and deal_indicator_ok == 0:
                        deal_indicator_ok = 1
                        abs_val = abs(emotion_indicator - 2.08)
                        emotion_indicator = 40 + abs_val * (30 / 0.48)
                    if emotion_indicator < 0.4 and deal_indicator_ok == 0:
                        deal_indicator_ok = 1
                        emotion_indicator = 40 - (emotion_indicator / 0.4) * 40
                    if emotion_indicator > 3.46 and deal_indicator_ok == 0:
                        deal_indicator_ok = 1
                        emotion_indicator = 40 - (emotion_indicator - 3.46) * (40 / 1.54)
                    # 格式化为一位小数
                    emotion_indicator = float("{:.1f}".format(emotion_indicator))
                    if emotion_indicator > 100:
                        emotion_indicator = 100
                    if hrv_watch_test and emotion_indicator < 40:
                        hrv_watch_test = False
                        summary['hrv_watch_exception_cnt'] += 1
                    ## 判断疲劳指数是否异常
                    if hrv_watch_test and (d['FatigueIndex'] < 40):
                        hrv_watch_test = False
                        summary['hrv_watch_exception_cnt'] += 1
                    ## 抗压指数是否异常
                    if hrv_watch_test and (d['CompressionResistanceIndex'] < 40):
                        hrv_watch_test = False
                        summary['hrv_watch_exception_cnt'] += 1
                    ## 获取用户当日平分
                    user_summary['score'] += d['Score']
                if not hr_test or not pressure_test:
                    summary['hr_pressure_exception_cnt'] += 1
                if len(data) != 0:
                    user_summary['score'] /= len(data)
                ## 如果data没数据，last_summary_btm就设置为None
                if len(data) == 0:
                    user_summary['last_summary_btm'] = None
                    ## 不填入last_summary_btm
                    sql = "INSERT INTO single_summary (`mac`, `summary_date`, `rr_pause_cnt`, `create_time`, `score`) VALUES ('" + \
                          user_summary['mac'] + "', '" + user_summary['summary_date'] + "', '" + str(
                        user_summary['rr_pause_cnt']) + "', '" + user_summary['create_time'] + "', '" + str(
                        user_summary['score']) + "')"
                else:
                    ## 最后一次总结的btm
                    user_summary['last_summary_btm'] = data[-1]['BTM'].strftime("%Y-%m-%d %H:%M:%S")
                    sql = "INSERT INTO single_summary (`mac`, `summary_date`, `rr_pause_cnt`, `create_time`, `last_summary_btm`, `score`) VALUES ('" + \
                          user_summary['mac'] + "', '" + user_summary['summary_date'] + "', '" + str(
                        user_summary['rr_pause_cnt']) + "', '" + user_summary['create_time'] + "', '" + user_summary[
                              'last_summary_btm'] + "', '" + str(user_summary['score']) + "')"

                ## 执行并判断是否插入成功
                if execute_update(sql) != 1:
                    raise Exception('插入single_summary数据失败')
                summary['average_score'] += user_summary['score']
                ## 判断是否有异常
                if not hr_test or not pressure_test or not rr_test or not sleep_test or not hrv_watch_test or not cv_test or not exception_test:
                    summary['exception_cnt'] += 1
            if len(userData) != 0:
                summary['average_score'] /= len(userData)
            summary['all_cnt'] = len(userData)
            sql = "INSERT INTO summary (`summary_date`, `hr_exception_cnt`, `pressure_exception_cnt`, `rr_exception_cnt`, `sleep_exception_cnt`, `hrv_watch_exception_cnt`, `all_cnt`, `exception_cnt`, `average_score`, `cv_exception_cnt`, `create_time`, `hr_overspeed_cnt`, `hr_slowspeed_cnt`, `rr_overspeed_cnt`, `rr_slowspeed_cnt`, `deep_light_sleep_exception_cnt`, `rem_exception_cnt`, `sleep_cycle_exception_cnt`, `hr_pressure_exception_cnt`, `rr_pause_cnt`) VALUES ('" + \
                  summary['summary_date'] + "', '" + str(summary['hr_exception_cnt']) + "', '" + str(
                summary['pressure_exception_cnt']) + "', '" + str(summary['rr_exception_cnt']) + "', '" + str(
                summary['sleep_exception_cnt']) + "', '" + str(summary['hrv_watch_exception_cnt']) + "', '" + str(
                summary['all_cnt']) + "', '" + str(summary['exception_cnt']) + "', '" + str(
                summary['average_score']) + "', '" + str(summary['cv_exception_cnt']) + "', '" + summary[
                      'create_time'] + "', '" + str(summary['hr_overspeed_cnt']) + "', '" + str(summary['hr_slowspeed_cnt']) + "', '" + str(summary['rr_overspeed_cnt']) + "', '" + str(summary['rr_slowspeed_cnt']) + "', '" + str(summary['deep_light_sleep_exception_cnt']) + "', '" + str(summary['rem_exception_cnt']) + "', '" + str(summary['sleep_cycle_exception_cnt']) + "', '" + str(summary['hr_pressure_exception_cnt']) + "', '" + str(summary['rr_pause_cnt']) + "')"
            ## 执行并判断是否插入成功
            if execute_update(sql) != 1:
                raise Exception('插入summary数据失败')




        except Exception as e:
            summary_logger.error(f"生成每日总结时出错: {str(e)}", exc_info=True)



# 创建默认的每日汇总器实例
_default_summarizer = None
# 标记是否已启动
_summary_started = False


def get_summarizer():
    """获取每日汇总器实例

    Returns:
        DailyDataSummarizer: 每日数据汇总器实例
    """
    global _default_summarizer
    if _default_summarizer is None:
        _default_summarizer = DailyDataSummarizer()
    return _default_summarizer


def start_summary(scheduler=None):
    """启动每日汇总任务

    Args:
        scheduler: 调度器实例，如果为None则尝试从scheduler模块获取

    Returns:
        DailyDataSummarizer: 每日数据汇总器实例
    """
    global _summary_started

    if scheduler is None:
        try:
            from utils.scheduler import get_scheduler
            scheduler = get_scheduler()
        except ImportError:
            summary_logger.error("无法导入调度器模块，每日总结任务无法启动")
            return None

    if _summary_started:
        summary_logger.info("每日总结任务已经在运行中，跳过重复启动")
        return get_summarizer()

    summarizer = get_summarizer()
    summarizer.start(scheduler)
    _summary_started = True
    return summarizer


def stop_summary(scheduler=None):
    """停止每日汇总任务

    Args:
        scheduler: 调度器实例，如果为None则尝试从scheduler模块获取
    """
    global _default_summarizer

    if scheduler is None and _default_summarizer is not None:
        try:
            from utils.scheduler import get_scheduler
            scheduler = get_scheduler()
        except ImportError:
            summary_logger.error("无法导入调度器模块，每日总结任务无法停止")
            return

    if _default_summarizer is not None:
        _default_summarizer.stop(scheduler)